﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace PowerManager_V1._0
{
    //智能电源设备命令代码
    public enum CommandState : int
    {
        NULL = 0,//空指令
        F1OPEN = 11,//打开负载1
        F1CLOSE = 10,//关闭负载1
        F2OPEN = 21,//打开负载2
        F2CLOSE = 20,//关闭负载2
        F3OPEN = 31,//打开负载3
        F3CLOSE = 30,//关闭负载3
        F4OPEN = 41,//打开负载4
        F4CLOSE = 40,//关闭负载4
        SOLARPOWERSUPPLY = 50,//打开太阳能供电
        ACPOWERSUPPLY = 51,//打开交流供电
        BATTERYASUPPLY = 60,//A组电池供电
        BATTERYBSUPPLY = 61//B组电池供电   
    }
    public enum BatteryState//电池状态
    {
        未连接,
        充电中,
        供电中,
        欠压供电,
        欠压,
        离线
    }
    public enum PowerState //电源状态
    {
        充电源故障,
        交流电,
        太阳能
    }
    public enum PowerLedState : short //充电源指示灯
    {
        太阳能,
        交流电
    }
    public enum LoadSate : short //负载状态
    {
        打开,
        关闭
    }

    public partial class Form1 : Form
    {

        private Socket powerClientSocket;
        private Socket clientSocket;
        private string serverIpAddress = "192.168.1.100";
        private int serverPort = 1000;

        private delegate void OnValueChangeEvent(Dictionary<string, float> dataDic);//数据更新委托事件
        private event OnValueChangeEvent OnValueChange;
        private byte[] dataByte = new byte[28];//存储接收到的数据
        private Dictionary<string, float> dataDic = new Dictionary<string, float>();//存储数据
        private Dictionary<string, Socket> clientDic = new Dictionary<string, Socket>();//存储客户端列表信息
        private Form1 form1;
       // private Log log = new Log();
        public bool F1isOpen = false;//智能电源负载1是否打开
        public bool F2isOpen = false;//负载2是否打开
        public bool F3isOpen = false;//负载3是否打开
        public bool F4isOpen = false;//负载4是否打开
        public BatteryState batteryAState, batteryBState;//电池A,B的状态
        public PowerState powerState;//电源状态
        public PowerLedState powerLedState;//充电led指示灯状态
        public LoadSate load1State, load2State, load3State, load4State;//负载状态
        public string message;
        bool isClientConnected = false;
        bool isClosed = false;
        Thread clientThread;
        #region 业务数据
        private float ac;
        public float AC//交流电压
        {
            get { return ac; }
            set
            {
                ac = value;
                writeToDic("交流电压", ac);
            }
        }
        private float av;
        public float AV//电池A电压
        {
            get { return av; }
            set
            {
                av = value;
                writeToDic("电池A电压", av);
            }
        }
        private float bv;
        public float BV
        {
            get { return bv; }
            set
            {
                bv = value;
                writeToDic("电池B电压", bv);
            }
        }
        private float f1v;
        public float F1V
        {
            get { return f1v; }
            set
            {
                f1v = value;
                writeToDic("负载1电压", f1v);
            }
        }
        private float f1a;
        public float F1A
        {
            get { return f1a; }
            set
            {
                f1a = value;
                writeToDic("负载1电流", f1a);
            }
        }
        private float f2v;
        public float F2V
        {
            get { return f2v; }
            set
            {
                f2v = value;
                writeToDic("负载2电压", f2v);
            }
        }
        private float f2a;
        public float F2A
        {
            get { return f2a; }
            set
            {
                f2a = value;
                writeToDic("负载2电流", f2a);
            }
        }
        private float f3v;
        public float F3V
        {
            get { return f3v; }
            set
            {
                f3v = value;
                writeToDic("负载3电压", f3v);
            }
        }
        private float f3a;
        public float F3A
        {
            get { return f3a; }
            set
            {
                f3a = value;
                writeToDic("负载3电流", f3a);
            }
        }
        private float f4v;
        public float F4V
        {
            get { return f4v; }
            set
            {
                f4v = value;
                writeToDic("负载4电压", f4v);
            }
        }
        private float f4a;
        public float F4A
        {
            get { return f4a; }
            set
            {
                f4a = value;
                writeToDic("负载4电流", f4a);
            }
        }
        #endregion

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Init();
        }

        //初始化
        private void Init()
        {
            textBox3.Text = serverIpAddress;
            textBox5.Text = serverPort.ToString();
            StartServer();//启动服务器
        }
        //开启服务器
        private void StartServer()
        {
            try
            {
                powerClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                powerClientSocket.Bind(new IPEndPoint(IPAddress.Parse(serverIpAddress), serverPort));
                powerClientSocket.Listen(20);//监听20个客户端的链接
                Thread threadWatch = new Thread(Connectiing);
                threadWatch.IsBackground = true;
                threadWatch.Start();
                //log.LogOutPut("服务器启动成功，正在监听客户端链接...");
                //form1.AppendString("服务器已经打开");
            }
            catch
            {
                //form1.AppendString("服务器已经失败");
            }

        }
        //监听客户端发送过来的链接
        private void Connectiing()
        {
            Socket connectSocket = null;
            while (true)
            {
                try
                {
                    connectSocket = powerClientSocket.Accept();

                }
                catch
                {
                   // log.LogOutPut("客户端链接失败，继续监听...");
                    isClientConnected = false;
                    continue;
                }
                IPAddress clientIPAddress = (connectSocket.RemoteEndPoint as IPEndPoint).Address;//获取客户端ip地址
                int clientPort = (connectSocket.RemoteEndPoint as IPEndPoint).Port;//获取客户端端口号

                string remoteEndPoint = (connectSocket.RemoteEndPoint).ToString();//获取客户端网络节点号
                //log.LogOutPut("监听到客户端IP:" + clientIPAddress + "  Port:" + clientPort + "的链接");
                //log.LogOutPut("成功与客户端" + remoteEndPoint + "建立链接");
                //form1.AppendString("与客户端成功建立链接");
                isClientConnected = true;
                Socket clientSocket = null;
                if (clientDic.TryGetValue(remoteEndPoint, out clientSocket))//如果已经存储，则更新
                    clientDic[remoteEndPoint] = connectSocket;
                else
                    clientDic.Add(remoteEndPoint, connectSocket);//如果未存储，则添加
                clientThread = new Thread(() =>//使用委托传递参数
                {
                    clientThread_Receive(connectSocket);
                });
                clientThread.IsBackground = true;
                clientThread.Start();//启动线程
            }
        }
        //此线程持续接收客户端发送过来的数据
        private void clientThread_Receive(Socket connectSocket)
        {
            //form1.AppendString("已经成功接收到客户端发送过来的数据");
            clientSocket = connectSocket;
            dataByte = null;
            while (true)
            {
                byte[] arrServerRecMsg = new byte[28];
                try
                {
                    int length = clientSocket.Receive(arrServerRecMsg);
                    dataByte = Converter.TakeOutByteNoOrder(arrServerRecMsg, 0, 28);

                }
                catch
                {
                    //form1.AppendString("接收数据出现错误");
                }
                SegmentDate(arrServerRecMsg);

            }
        }
        //接收命令代码
        public void ReceiverCommand(CommandState commandState)
        {
            if (commandState == CommandState.NULL) return;
            switch (commandState)
            {
                case CommandState.F1OPEN:
                    SendCommand(DateConfig.openF1);
                    break;
                case CommandState.F1CLOSE:
                    SendCommand(DateConfig.closeF1);
                    break;
                case CommandState.F2OPEN:
                    SendCommand(DateConfig.openF2);
                    break;
                case CommandState.F2CLOSE:
                    SendCommand(DateConfig.closeF2);
                    break;
                case CommandState.F3OPEN:
                    SendCommand(DateConfig.openF3);
                    break;
                case CommandState.F3CLOSE:
                    SendCommand(DateConfig.closeF3);
                    break;
                case CommandState.F4OPEN:
                    SendCommand(DateConfig.openF4);
                    break;
                case CommandState.F4CLOSE:
                    SendCommand(DateConfig.closeF4);
                    break;
                case CommandState.SOLARPOWERSUPPLY:
                    SendCommand(DateConfig.solarPowerSupply);
                    break;
                case CommandState.ACPOWERSUPPLY:
                    SendCommand(DateConfig.acPowerSupply);
                    break;
                case CommandState.BATTERYASUPPLY:
                    SendCommand(DateConfig.batterASupply);
                    break;
                case CommandState.BATTERYBSUPPLY:
                    SendCommand(DateConfig.batterBSupply);
                    break;
                default:
                    break;
            }
        }

        private void SendCommand(byte[] command)
        {
            if (command.Length != 5)
            {
                //form1.AppendString("发送到智能电源设备的命令格式错误！请检查后重新发送...");
                return;
            }
            int length = clientSocket.Send(command);
            if (length > 0)
            {
                //form1.AppendString("命令发送成功");
            }
            else
            {
                //form1.AppendString("命令发送失败！");
            }
        }
        //分割数据
        private void SegmentDate(byte[] dateByte)
        {
            
            // byte[] dateTemp = Converter.TakeOutByteNoOrder(dateByte, 4, 2);
            //bool isLittleEndian = System.BitConverter.IsLittleEndian;
            float x = 100;
            AC = (float)Converter.BytesToShort(dateByte, 2);
            AV = (float)Converter.BytesToShort(dateByte, 4) / x;
            BV = (float)Converter.BytesToShort(dateByte, 6) / x;
            F1V = (float)Converter.BytesToShort(dataByte, 8) / x;
            F2V = (float)Converter.BytesToShort(dateByte, 10) / x;
            F3V = (float)Converter.BytesToShort(dateByte, 12) / x;
            F4V = (float)Converter.BytesToShort(dateByte, 14) / x;
            F1A = (float)Converter.BytesToShort(dataByte, 16) / x;
            F2A = (float)Converter.BytesToShort(dataByte, 18) / x;
            F3A = (float)Converter.BytesToShort(dataByte, 20) / x;
            F4A = (float)Converter.BytesToShort(dateByte, 22) / x;
            byte[] batteryStateTemp = new byte[1];//获取电池D23状态
            batteryStateTemp = Converter.TakeOutByte(dateByte, 24, 1);
            byte batteryAState = batteryStateTemp[0];
            batteryAState = (byte)((batteryAState & 0xF0) >> 4);//电池A的状态
            byte batteryBState = batteryStateTemp[0];
            batteryBState = (byte)(batteryBState & 0x0F);//电池B的状态

            byte[] powerStateTemp = new byte[1];//获取D24数据状态
            powerStateTemp = Converter.TakeOutByte(dateByte, 25, 1);
            byte powerState = powerStateTemp[0];
            powerState = (byte)(powerState >> 6);//获取电源状态
            byte powerLEDState = powerStateTemp[0];
            powerLEDState = (byte)((powerLEDState & 0x30) >> 4);//电源指示灯状态
            byte loadState = powerStateTemp[0];
            loadState = (byte)(loadState & 0x0F);//负载状态

            SegmentDateInter(batteryAState, batteryBState, powerState, powerLEDState, loadState);
            if (isClosed) return;
            AppendString(Environment.NewLine +Environment.NewLine +"\t交流电: " + AC + "V " + "电池A: " + AV + "V " + " 电池B: " + BV + "V " + Environment.NewLine +
                                 "\t负载1: " + F1V + "V " + "负载2: " + F2V + "V " + "负载3: " + F3V + "V " + "负载4: " + F4V + "V " + Environment.NewLine +
                                 "\t负载1: " + F1A + "A " + "负载2: " + F2A + "A " + "负载3: " + F3A + "A " + "负载4: " + F4A + "A " + Environment.NewLine + Environment.NewLine +
                                 "\t\t电池A状态: " + this.batteryAState.ToString() + " \t电池B状态: " + this.batteryBState.ToString() + Environment.NewLine +
                                 "\t\t电源状态: " + this.powerState.ToString() + " \t电源指示灯状态: " + this.powerLedState.ToString() + Environment.NewLine +
                                 "\t\t负载1状态: " + this.load1State.ToString() + " \t负载2状态: " + this.load2State.ToString() + Environment.NewLine +
                                 "\t\t负载3状态: " + this.load3State.ToString() + " \t负载4状态: " + this.load4State.ToString());

            UpdateButtonValue(this.load1State, this.load2State, this.load3State, this.load4State, this.powerState, this.batteryAState, this.batteryBState);//更新按钮颜色机文本
        }

        public void UpdateButtonValue(LoadSate load1State, LoadSate load2State, LoadSate load3State, LoadSate load4State, PowerState powerState, BatteryState batteryAState, BatteryState batteryBState)
        {

            switch ((short)batteryAState)
            {
                case 0:
                    AppendButtonShow(button17, "A未连接", Color.Blue);
                    break;
                case 1:
                    AppendButtonShow(button17, "A充电中", Color.Purple);
                    break;
                case 2:
                    AppendButtonShow(button17, "A供电中", Color.LightBlue);
                    break;
                case 3:
                    AppendButtonShow(button17, "A欠压供电", Color.Red);
                    break;
                case 4:
                    AppendButtonShow(button17, "A欠压", Color.Yellow);
                    break;
                case 5:
                    AppendButtonShow(button17, "A离线", Color.Gray);
                    break;
                default:
                    break;
            }
            switch ((short)batteryBState)
            {
                case 0:
                    AppendButtonShow(button18, "B未连接", Color.Blue);
                    break;
                case 1:
                    AppendButtonShow(button18, "B充电中", Color.Purple);
                    break;
                case 2:
                    AppendButtonShow(button18, "B供电中", Color.LightBlue);
                    break;
                case 3:
                    AppendButtonShow(button18, "B欠压供电", Color.Red);
                    break;
                case 4:
                    AppendButtonShow(button18, "B" + BatteryState.欠压.ToString(), Color.Yellow);
                    break;
                case 5:
                    AppendButtonShow(button18, "B离线", Color.Gray);
                    break;
                default:
                    break;
            }
            switch ((short)powerState)
            {
                case 0://充电故障
                    AppendButtonShow(button15, "充电故障", Color.Red);
                    break;
                case 1:
                    AppendButtonShow(button15, "交流供电中", Color.MediumBlue);
                    AppendButtonShow(button16, "太阳能供电", Color.Orange);
                    break;
                case 2:
                    AppendButtonShow(button15, "交流电供电", Color.Orange);
                    AppendButtonShow(button16, "太阳能供电中", Color.LightBlue);
                    break;
                default:
                    break;
            }
            if (load1State == LoadSate.打开)
            {
                F1isOpen = true;
                AppendButtonShow(button11, "负载1开", Color.LightBlue);
            }
            else
            {
                F1isOpen = false;
                AppendButtonShow(button11, "负载1关", Color.DarkGreen);
            }

            if (load2State == LoadSate.打开)
            {
                F2isOpen = true;
                AppendButtonShow(button12, "负载2开", Color.LightBlue);
            }
            else
            {
                F2isOpen = false;
                AppendButtonShow(button12, "负载2关", Color.DarkGreen);
            }

            if (load3State == LoadSate.打开)
            {
                F3isOpen = true;
                AppendButtonShow(button13, "负载3开", Color.LightBlue);
            }
            else
            {
                F3isOpen = false;
                AppendButtonShow(button13, "负载3关", Color.DarkGreen);
            }

            if (load4State == LoadSate.打开)
            {
                F4isOpen = true;
                AppendButtonShow(button14, "负载4开", Color.LightBlue);
            }
            else
            {
                F4isOpen = false;
                AppendButtonShow(button14, "负载4关", Color.DarkGreen);
            }


        }
        private void AppendString(string value)
        {
            if(outPutText.InvokeRequired)
            {

                 if (this.outPutText.Disposing || this.outPutText.IsDisposed)
                    return;
 
                outPutText.Invoke(new EventHandler((object o, EventArgs e) => { outPutText.Text = value; }));
            }
            else
            {
                outPutText.Text = value;
            }
        }
        //跨线程调用UI控件
        //跨线程更新UI的颜色属性不需要使用委托，可直接跨线程更改
        public void AppendButtonShow(Button button, string value, Color color)
        {
            switch (button.Name)
            {
                case "button11":
                    if (button11.InvokeRequired)
                    {
                        button11.Invoke(new EventHandler((object o, EventArgs e) => { this.button11.BackColor = color; this.button11.Text = value; }));
                    }
                    else
                    {
                        this.button11.BackColor = color; 
                        this.button11.Text = value;
                    }
                    break;
                case "button12":
                    if (button12.InvokeRequired)
                    {
                        button12.Invoke(new EventHandler((object o, EventArgs e) => { this.button12.BackColor = color; this.button12.Text = value; }));
                    }
                    else
                    {
                        this.button12.BackColor = color; 
                        this.button12.Text = value; 
                    }
                    break;
                case "button13":
                    if (button13.InvokeRequired)
                    {
                        button13.Invoke(new EventHandler((object o, EventArgs e) => { this.button13.BackColor = color; this.button13.Text = value; }));
                    }
                    else
                    {
                        this.button13.BackColor = color; 
                        this.button13.Text = value;
                    }
                    break;
                case "button14":
                    if (button14.InvokeRequired)
                    {

                        button14.Invoke(new EventHandler((object o, EventArgs e) => { this.button14.BackColor = color; this.button14.Text = value; }));
                    }
                    else
                    {
                        this.button14.BackColor = color;
                        this.button14.Text = value;
                    }
                    break;
                case "button15":
                    if (button15.InvokeRequired)
                    {

                        button15.Invoke(new EventHandler((object o, EventArgs e) => { this.button15.BackColor = color; this.button15.Text = value; }));
                    }
                    else
                    {
                        this.button15.BackColor = color; 
                        this.button15.Text = value;
                    }
                    break;
                case "button16":
                    if (button16.InvokeRequired)
                    {

                        button16.Invoke(new EventHandler((object o, EventArgs e) => { this.button16.BackColor = color; this.button16.Text = value; }));
                    }
                    else
                    {
                        this.button16.BackColor = color; 
                        this.button16.Text = value;
                    }
                    break;
                case "button17":
                    if (this.button17.InvokeRequired)
                    {
                        button17.Invoke(new EventHandler((object o, EventArgs e) => { this.button17.BackColor = color; this.button17.Text = value; }));
                    }
                    else
                    {
                        this.button17.BackColor = color; 
                        this.button17.Text = value;
                    }
                    break;
                case "button18":
                    if (button18.InvokeRequired)
                    {
                        button18.Invoke(new EventHandler((object o, EventArgs e) => { this.button18.BackColor = color; this.button18.Text = value; }));
                    }
                    else
                    {
                        this.button18.BackColor = color; 
                        this.button18.Text = value;
                    }
                    break;
                default:
                    break;
            }
        }


        /// <summary>
        /// 获取智能电源状态数据
        /// </summary>
        /// <param name="batteryAState">电池A状态</param>
        /// <param name="batteryBState">电池B状态</param>
        /// <param name="powerState">电源状态</param>
        /// <param name="powerLEDState">电源指示灯状态</param>
        /// <param name="loadState">负载状态</param>
        private void SegmentDateInter(byte batteryAState, byte batteryBState, byte powerState, byte powerLEDState, byte loadState)
        {
            switch ((short)batteryAState)
            {
                case 0:
                    this.batteryAState = BatteryState.未连接;
                    break;
                case 1:
                    this.batteryAState = BatteryState.充电中;
                    break;
                case 2:
                    this.batteryAState = BatteryState.供电中;
                    break;
                case 3:
                    this.batteryAState = BatteryState.欠压供电;
                    break;
                case 4:
                    this.batteryAState = BatteryState.欠压;
                    break;
                case 5:
                    this.batteryAState = BatteryState.离线;
                    break;
                default:
                    break;
            }
            switch ((short)batteryBState)
            {
                case 0:
                    this.batteryBState = BatteryState.未连接;
                    break;
                case 1:
                    this.batteryBState = BatteryState.充电中;
                    break;
                case 2:
                    this.batteryBState = BatteryState.供电中;
                    break;
                case 3:
                    this.batteryBState = BatteryState.欠压供电;
                    break;
                case 4:
                    this.batteryBState = BatteryState.欠压;
                    break;
                case 5:
                    this.batteryBState = BatteryState.离线;
                    break;
                default:
                    break;
            }
            switch ((short)powerState)
            {
                case 0:
                    this.powerState = PowerState.充电源故障;
                    break;
                case 1:
                    this.powerState = PowerState.交流电;
                    break;
                case 2:
                    this.powerState = PowerState.太阳能;
                    break;
                default:
                    break;
            }
            switch ((short)powerLEDState)
            {
                case 1:
                    this.powerLedState = PowerLedState.交流电;
                    break;
                case 2:
                    this.powerLedState = PowerLedState.太阳能;
                    break;
                default:
                    break;
            }
            //获取各个通道的状态
            this.load1State = ((loadState & 0x01) == 0) ? LoadSate.关闭 : LoadSate.打开;
            this.load2State = ((loadState & 0x02) == 0) ? LoadSate.关闭 : LoadSate.打开;
            this.load3State = ((loadState & 0x04) == 0) ? LoadSate.关闭 : LoadSate.打开;
            this.load4State = ((loadState & 0x08) == 0) ? LoadSate.关闭 : LoadSate.打开;
        }
        //像字典中写入数据
        private void writeToDic(string name, float value)
        {
            float data;
            if (dataDic.TryGetValue(name, out data))
            {
                dataDic[name] = value;
            }
            else
            {
                dataDic.Add(name, value);
            }
        }

        private void button11_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            if (F1isOpen == false)
            {
                ReceiverCommand(CommandState.F1OPEN);
                F1isOpen = true;
                button11.BackColor = Color.LightBlue;
                button11.Text = "负载1开";
            }
            else
            {
                ReceiverCommand(CommandState.F1CLOSE);
                F1isOpen = false;
                button11.BackColor = Color.DarkGreen;
                button11.Text = "负载1关";
            }
        }

        private void button12_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            if (F2isOpen == false)
            {
                ReceiverCommand(CommandState.F2OPEN);
                F2isOpen = true;
                button12.BackColor = Color.LightBlue;
                button12.Text = "负载2开";
            }
            else
            {
                ReceiverCommand(CommandState.F2CLOSE);
                F2isOpen = false;
                button12.BackColor = Color.DarkGreen;
                button12.Text = "负载2关";
            }
        }

        private void button13_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            if (F3isOpen == false)
            {
                ReceiverCommand(CommandState.F3OPEN);
                F3isOpen = true;
                button13.BackColor = Color.LightBlue;
                button13.Text = "负载3开";
            }
            else
            {
                ReceiverCommand(CommandState.F3CLOSE);
                F3isOpen = false;
                button13.BackColor = Color.DarkGreen;
                button13.Text = "负载3关";
            }
        }

        private void button14_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            if (F4isOpen == false)
            {
                ReceiverCommand(CommandState.F4OPEN);
                F4isOpen = true;
                button14.BackColor = Color.LightBlue;
                button14.Text = "负载4开";
            }
            else
            {
                ReceiverCommand(CommandState.F4CLOSE);
                F4isOpen = false;
                button14.BackColor = Color.DarkGreen;
                button14.Text = "负载4关";
            }
           
        }

        private void button15_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            ReceiverCommand(CommandState.ACPOWERSUPPLY);
            button15.BackColor = Color.MediumBlue;
            button15.Text = "交流供电中";
            button16.BackColor = Color.Orange;
            button16.Text = "太阳能供电";
        }

        private void button16_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            ReceiverCommand(CommandState.SOLARPOWERSUPPLY);
            button16.BackColor = Color.MediumBlue;
            button16.Text = "太阳能供电中";
            button15.BackColor = Color.Orange;
            button15.Text = "交流供电";
        }

        private void button17_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            ReceiverCommand(CommandState.BATTERYASUPPLY);
            button17.BackColor = Color.LightBlue;
            button17.Text = "A组供电中";
            button18.BackColor = Color.Purple;
            button18.Text = "B组供电";
        }
        private void button18_Click(object sender, EventArgs e)
        {
            if (!isClientConnected) return;
            ReceiverCommand(CommandState.BATTERYBSUPPLY);
            button18.BackColor = Color.LightBlue;
            button18.Text = "B组供电中";
            button17.BackColor = Color.Purple;
            button17.Text = "A组供电";
        }
        protected override void OnClosed(EventArgs e)
        {
            isClosed = true;
            base.OnClosed(e);
            if (clientSocket != null)
                clientSocket.Shutdown(SocketShutdown.Both);
            clientDic.Clear();
            dataDic.Clear();
            if(isClientConnected)
            clientThread.Abort();
        }
    }
}
